#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""记事本功能模块"""

import os
from datetime import datetime
from PyQt5.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QTextEdit, QPushButton,
    QFileDialog, QMessageBox, QLabel, QSplitter, QTreeWidget, QTreeWidgetItem,
    QInputDialog, QFontComboBox, QSpinBox, QColorDialog, QToolBar, QAction
)
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtGui import QFont, QColor

# 导入日志模块
from logger_module import log_info, log_error
# 导入数据库工具类
from db_utils import DatabaseUtils

class NotepadTab(QWidget):
    """记事本标签页类"""
    # 数据更新信号，用于通知主窗口
    data_updated = pyqtSignal()
    
    def __init__(self):
        """初始化记事本标签页"""
        super().__init__()
        # 初始化笔记数据
        self.notes = {}
        self.current_note = "未命名笔记"
        # 存储笔记的时间信息和序号
        self.notes_metadata = {}
        # 初始化UI
        self.initUI()
        # 加载保存的笔记
        self.load_notes()
        log_info("记事本模块初始化完成")
    
    def initUI(self):
        """初始化用户界面"""
        # 创建主布局
        main_layout = QVBoxLayout(self)
        
        # 创建分割器
        splitter = QSplitter(Qt.Horizontal)
        
        # 创建左侧笔记列表，支持多列显示
        self.notes_list_widget = QTreeWidget()
        self.notes_list_widget.setColumnCount(3)
        self.notes_list_widget.setHeaderLabels(["序号", "笔记名称", "最后修改时间"])
        # 设置列宽
        self.notes_list_widget.setColumnWidth(0, 40)
        self.notes_list_widget.setColumnWidth(1, 150)
        self.notes_list_widget.setColumnWidth(2, 180)
        
        self.notes_list_widget.setMinimumWidth(400)
        self.notes_list_widget.setMaximumWidth(500)
        self.notes_list_widget.itemClicked.connect(self.on_note_selected)
        
        # 创建右侧编辑区域
        edit_widget = QWidget()
        edit_layout = QVBoxLayout(edit_widget)
        
        # 创建笔记标题
        title_layout = QHBoxLayout()
        self.note_title = QLabel("未命名笔记")
        self.note_title.setFont(QFont("Microsoft YaHei", 12, QFont.Bold))
        title_layout.addWidget(self.note_title)
        title_layout.addStretch()
        
        # 创建工具栏
        toolbar_layout = QHBoxLayout()
        
        # 创建操作按钮
        new_btn = QPushButton("新建笔记")
        new_btn.clicked.connect(self.new_note)
        toolbar_layout.addWidget(new_btn)
        
        save_btn = QPushButton("保存笔记")
        save_btn.clicked.connect(self.save_note)
        toolbar_layout.addWidget(save_btn)
        
        rename_btn = QPushButton("重命名")
        rename_btn.clicked.connect(self.rename_note)
        toolbar_layout.addWidget(rename_btn)
        
        delete_btn = QPushButton("删除笔记")
        delete_btn.clicked.connect(self.delete_note)
        toolbar_layout.addWidget(delete_btn)
        
        export_btn = QPushButton("导出笔记")
        export_btn.clicked.connect(self.export_note)
        toolbar_layout.addWidget(export_btn)
        
        toolbar_layout.addStretch()
        
        # 创建格式工具栏
        self.init_format_toolbar(edit_layout)
        
        # 创建文本编辑区域
        self.text_edit = QTextEdit()
        self.text_edit.setPlaceholderText("在这里输入笔记内容...")
        self.text_edit.setAcceptRichText(True)
        self.text_edit.textChanged.connect(self.on_text_changed)
        
        # 添加组件到编辑布局
        edit_layout.addLayout(title_layout)
        edit_layout.addLayout(toolbar_layout)
        edit_layout.addWidget(self.text_edit)
        
        # 添加组件到分割器
        splitter.addWidget(self.notes_list_widget)
        splitter.addWidget(edit_widget)
        splitter.setSizes([200, 600])
        
        # 添加分割器到主布局
        main_layout.addWidget(splitter)
        
        # 设置布局
        self.setLayout(main_layout)
    
    def init_format_toolbar(self, parent_layout):
        """初始化文本格式工具栏"""
        # 创建格式工具栏
        format_toolbar = QToolBar("文本格式")
        
        # 字体选择器
        font_label = QLabel("字体:")
        self.font_combo = QFontComboBox()
        self.font_combo.currentFontChanged.connect(self.change_font)
        format_toolbar.addWidget(font_label)
        format_toolbar.addWidget(self.font_combo)
        
        # 字号调整器
        size_label = QLabel("字号:")
        self.font_size_spin = QSpinBox()
        self.font_size_spin.setRange(8, 72)
        self.font_size_spin.setValue(12)
        self.font_size_spin.valueChanged.connect(self.change_font_size)
        format_toolbar.addWidget(size_label)
        format_toolbar.addWidget(self.font_size_spin)
        
        # 加粗按钮
        self.bold_action = QAction("加粗", self)
        self.bold_action.setCheckable(True)
        self.bold_action.triggered.connect(self.toggle_bold)
        format_toolbar.addAction(self.bold_action)
        
        # 斜体按钮
        self.italic_action = QAction("斜体", self)
        self.italic_action.setCheckable(True)
        self.italic_action.triggered.connect(self.toggle_italic)
        format_toolbar.addAction(self.italic_action)
        
        # 下划线按钮
        self.underline_action = QAction("下划线", self)
        self.underline_action.setCheckable(True)
        self.underline_action.triggered.connect(self.toggle_underline)
        format_toolbar.addAction(self.underline_action)
        
        # 颜色按钮
        color_btn = QPushButton("字体颜色")
        color_btn.clicked.connect(self.change_text_color)
        format_toolbar.addWidget(color_btn)
        
        # 将工具栏添加到父布局
        parent_layout.addWidget(format_toolbar)
    
    def change_font(self, font):
        """更改选中文本的字体"""
        cursor = self.text_edit.textCursor()
        char_format = cursor.charFormat()
        char_format.setFontFamily(font.family())
        
        if cursor.hasSelection():
            cursor.mergeCharFormat(char_format)
        else:
            cursor.setCharFormat(char_format)
    
    def change_font_size(self, size):
        """更改选中文本的字号"""
        cursor = self.text_edit.textCursor()
        char_format = cursor.charFormat()
        char_format.setFontPointSize(size)
        
        if cursor.hasSelection():
            cursor.mergeCharFormat(char_format)
        else:
            cursor.setCharFormat(char_format)
    
    def toggle_bold(self, checked):
        """切换选中文本的加粗状态"""
        cursor = self.text_edit.textCursor()
        font = cursor.charFormat()
        font.setFontWeight(QFont.Bold if checked else QFont.Normal)
        
        if cursor.hasSelection():
            cursor.mergeCharFormat(font)
        else:
            cursor.setCharFormat(font)
    
    def toggle_italic(self, checked):
        """切换选中文本的斜体状态"""
        cursor = self.text_edit.textCursor()
        font = cursor.charFormat()
        font.setFontItalic(checked)
        
        if cursor.hasSelection():
            cursor.mergeCharFormat(font)
        else:
            cursor.setCharFormat(font)
    
    def toggle_underline(self, checked):
        """切换选中文本的下划线状态"""
        cursor = self.text_edit.textCursor()
        font = cursor.charFormat()
        font.setFontUnderline(checked)
        
        if cursor.hasSelection():
            cursor.mergeCharFormat(font)
        else:
            cursor.setCharFormat(font)
    
    def change_text_color(self):
        """更改选中文本的颜色"""
        color = QColorDialog.getColor()
        if color.isValid():
            self.text_edit.setTextColor(color)
    
    def ensure_notes_table_exists(self):
        """确保notes表存在于数据库中"""
        try:
            conn = DatabaseUtils.get_connection()
            if conn:
                cursor = conn.cursor()
                cursor.execute('''
                CREATE TABLE IF NOT EXISTS notes (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    note_name TEXT NOT NULL UNIQUE,
                    content TEXT,
                    created_at TEXT NOT NULL,
                    updated_at TEXT NOT NULL
                )
                ''')
                conn.commit()
                DatabaseUtils.close_connection(conn)
        except Exception as e:
            log_error(f"确保notes表存在时出错: {str(e)}")
    
    def load_notes(self):
        """从数据库加载笔记数据"""
        try:
            # 确保notes表存在
            self.ensure_notes_table_exists()
            
            # 从数据库加载笔记
            conn = DatabaseUtils.get_connection()
            if conn:
                cursor = conn.cursor()
                cursor.execute("SELECT note_name, content, created_at, updated_at FROM notes ORDER BY updated_at DESC")
                rows = cursor.fetchall()
                
                # 将查询结果转换为字典
                self.notes = {}
                self.notes_metadata = {}
                
                for row in rows:
                    note_name = row['note_name']
                    self.notes[note_name] = row['content'] if row['content'] else ""
                    self.notes_metadata[note_name] = {
                        'created_at': row['created_at'],
                        'updated_at': row['updated_at']
                    }
                
                # 如果没有笔记，创建默认笔记
                current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                if not self.notes:
                    self.notes = {"未命名笔记": ""}
                    self.notes_metadata["未命名笔记"] = {
                        'created_at': current_time,
                        'updated_at': current_time
                    }
                    self.save_notes()
                
                # 更新笔记列表
                self.update_notes_list()
                DatabaseUtils.close_connection(conn)
            else:
                # 创建默认笔记
                self.init_default_note()
        except Exception:
            # 创建默认笔记
            self.init_default_note()
    
    def init_default_note(self):
        """创建默认笔记"""
        current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        self.notes = {"未命名笔记": ""}
        self.notes_metadata["未命名笔记"] = {
            'created_at': current_time,
            'updated_at': current_time
        }
    
    def save_notes(self):
        """保存笔记数据到数据库"""
        try:
            conn = DatabaseUtils.get_connection()
            if conn:
                cursor = conn.cursor()
                current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                
                # 遍历所有笔记，更新或插入数据
                for note_name, content in self.notes.items():
                    # 检查笔记是否已存在
                    cursor.execute("SELECT id FROM notes WHERE note_name = ?", (note_name,))
                    existing = cursor.fetchone()
                    
                    if existing:
                        # 更新现有笔记
                        cursor.execute(
                            "UPDATE notes SET content = ?, updated_at = ? WHERE id = ?",
                            (content, current_time, existing['id'])
                        )
                        # 更新内存中的元数据
                        if note_name in self.notes_metadata:
                            self.notes_metadata[note_name]['updated_at'] = current_time
                    else:
                        # 插入新笔记
                        cursor.execute(
                            "INSERT INTO notes (note_name, content, created_at, updated_at) VALUES (?, ?, ?, ?)",
                            (note_name, content, current_time, current_time)
                        )
                        # 更新内存中的元数据
                        self.notes_metadata[note_name] = {
                            'created_at': current_time,
                            'updated_at': current_time
                        }
                
                conn.commit()
                DatabaseUtils.close_connection(conn)
                self.data_updated.emit()
                return True
            else:
                QMessageBox.warning(self, "保存失败", "无法连接到数据库")
                return False
        except Exception as e:
            log_error(f"保存笔记失败: {str(e)}")
            QMessageBox.warning(self, "保存失败", f"无法保存笔记: {str(e)}")
            return False
    
    def update_notes_list(self):
        """更新笔记列表显示"""
        # 清空当前列表
        self.notes_list_widget.clear()
        
        # 添加笔记到列表，并显示序号和时间
        sorted_notes = sorted(self.notes.items(), key=lambda x: 
                            (self.notes_metadata.get(x[0], {}).get('updated_at', ''), x[0]), 
                            reverse=True)
        
        for idx, (note_name, _) in enumerate(sorted_notes, 1):
            # 获取笔记的更新时间
            updated_at = self.notes_metadata.get(note_name, {}).get('updated_at', '未知')
            
            # 创建带有序号、名称和时间的项
            item = QTreeWidgetItem([str(idx), note_name, updated_at])
            self.notes_list_widget.addTopLevelItem(item)
            
            # 高亮显示当前选中的笔记
            if note_name == self.current_note:
                self.notes_list_widget.setCurrentItem(item)
    
    def new_note(self):
        """创建新笔记"""
        # 保存当前笔记
        if self.current_note in self.notes:
            self.save_note()
        
        # 生成新笔记名称
        counter = 1
        new_note_name = f"未命名笔记{counter}"
        while new_note_name in self.notes:
            counter += 1
            new_note_name = f"未命名笔记{counter}"
        
        # 添加新笔记
        current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        self.notes[new_note_name] = ""
        self.notes_metadata[new_note_name] = {
            'created_at': current_time,
            'updated_at': current_time
        }
        self.current_note = new_note_name
        
        # 更新UI
        self.note_title.setText(new_note_name)
        self.text_edit.clear()
        self.update_notes_list()
        log_info(f"创建新笔记: {new_note_name}")
    
    def save_note(self):
        """保存当前笔记"""
        # 获取文本内容
        content = self.text_edit.toPlainText()
        # 更新笔记内容
        self.notes[self.current_note] = content
        # 保存到数据库
        self.save_notes()
        QMessageBox.information(self, "保存成功", f"笔记 '{self.current_note}' 已保存")
    
    def delete_note(self):
        """删除当前笔记"""
        # 检查是否只有一条笔记
        if len(self.notes) <= 1:
            QMessageBox.warning(self, "无法删除", "至少需要保留一条笔记")
            return
        
        # 确认删除
        reply = QMessageBox.question(
            self, "确认删除", 
            f"确定要删除笔记 '{self.current_note}' 吗？此操作不可撤销。",
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No
        )
        
        if reply == QMessageBox.Yes:
            note_to_delete = self.current_note
            # 从内存中删除笔记
            del self.notes[self.current_note]
            # 同时删除元数据
            if self.current_note in self.notes_metadata:
                del self.notes_metadata[self.current_note]
            # 选择第一条笔记
            self.current_note = list(self.notes.keys())[0]
            # 更新UI
            self.note_title.setText(self.current_note)
            self.text_edit.setPlainText(self.notes[self.current_note])
            self.update_notes_list()
            
            # 从数据库中删除笔记
            try:
                conn = DatabaseUtils.get_connection()
                if conn:
                    cursor = conn.cursor()
                    cursor.execute("DELETE FROM notes WHERE note_name = ?", (note_to_delete,))
                    conn.commit()
                    DatabaseUtils.close_connection(conn)
            except Exception as e:
                log_error(f"删除笔记失败: {str(e)}")
                QMessageBox.warning(self, "删除失败", f"无法从数据库删除笔记: {str(e)}")
            
            self.data_updated.emit()
            log_info(f"删除笔记: {note_to_delete}")
    
    def export_note(self):
        """导出当前笔记为文本文件"""
        # 获取文件路径
        file_path, _ = QFileDialog.getSaveFileName(
            self, "导出笔记", 
            f"{self.current_note}.txt", 
            "文本文件 (*.txt);;所有文件 (*)"
        )
        
        if file_path:
            try:
                with open(file_path, "w", encoding="utf-8") as f:
                    f.write(self.text_edit.toPlainText())
                QMessageBox.information(self, "导出成功", f"笔记已导出到: {file_path}")
                log_info(f"导出笔记 '{self.current_note}' 到文件: {file_path}")
            except Exception as e:
                log_error(f"导出笔记失败: {str(e)}")
                QMessageBox.warning(self, "导出失败", f"无法导出笔记: {str(e)}")
    
    def on_note_selected(self, item, column):
        """当选择笔记时触发"""
        # 始终获取第二列的笔记名称，无论点击哪一列
        note_name = item.text(1)
        
        # 检查是否有未保存的更改
        if self.current_note in self.notes:
            current_content = self.text_edit.toPlainText()
            if current_content != self.notes[self.current_note]:
                reply = QMessageBox.question(
                    self, "未保存的更改", 
                    "当前笔记有未保存的更改，是否保存？",
                    QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel
                )
                
                if reply == QMessageBox.Cancel:
                    # 取消操作，重新选中之前的笔记
                    self.update_notes_list()
                    return
                elif reply == QMessageBox.Yes:
                    # 保存当前笔记
                    self.notes[self.current_note] = current_content
                    self.save_notes()
        
        # 更新当前笔记
        self.current_note = note_name
        self.note_title.setText(note_name)
        self.text_edit.setPlainText(self.notes[note_name])
    
    def rename_note(self):
        """重命名当前笔记"""
        # 使用QInputDialog获取新的笔记名称
        new_name, ok = QInputDialog.getText(
            self, "重命名笔记", 
            "请输入新的笔记名称:", 
            text=self.current_note
        )
        
        if ok and new_name:
            # 去除首尾空格
            new_name = new_name.strip()
            
            # 检查名称是否为空
            if not new_name:
                QMessageBox.warning(self, "名称无效", "笔记名称不能为空")
                return
            
            # 检查名称是否已存在（排除当前笔记）
            if new_name in self.notes and new_name != self.current_note:
                QMessageBox.warning(self, "名称已存在", f"笔记 '{new_name}' 已存在")
                return
            
            # 如果名称没有变化，直接返回
            if new_name == self.current_note:
                return
            
            try:
                # 从数据库中更新笔记名称
                conn = DatabaseUtils.get_connection()
                if conn:
                    cursor = conn.cursor()
                    current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                    cursor.execute(
                        "UPDATE notes SET note_name = ?, updated_at = ? WHERE note_name = ?",
                        (new_name, current_time, self.current_note)
                    )
                    conn.commit()
                    DatabaseUtils.close_connection(conn)
                    
                    # 更新内存中的笔记数据
                    content = self.notes[self.current_note]
                    del self.notes[self.current_note]
                    self.notes[new_name] = content
                    
                    # 更新元数据
                    if self.current_note in self.notes_metadata:
                        self.notes_metadata[new_name] = self.notes_metadata[self.current_note]
                        del self.notes_metadata[self.current_note]
                    
                    # 更新当前笔记名称
                    self.current_note = new_name
                        
                    # 更新UI
                    self.note_title.setText(new_name)
                    self.update_notes_list()
                    
                    self.data_updated.emit()
                    log_info(f"将笔记重命名为: {new_name}")
                else:
                    QMessageBox.warning(self, "重命名失败", "无法连接到数据库")
                    
            except Exception as e:
                log_error(f"重命名笔记失败: {str(e)}")
                QMessageBox.warning(self, "重命名失败", f"无法重命名笔记: {str(e)}")
    
    def on_text_changed(self):
        """当文本内容变化时触发"""
        # 文本变化事件处理，暂不实现自动保存